function KeyPress() {
    this.keyListeners = []
}

KeyPress.prototype = {
    addKeyListener: function(keyAndListener) {
        this.keyListeners.push(keyAndListener)
    },

    findKeyListener: function(key) {
        var listener = undefined

        this.keyListeners.forEach(function(keyAndListener) {
            var currentKey = keyAndListener.key
            if(currentKey === key) {
                listener = keyAndListener.listener
            }
        })

        return listener
    },

    keyPressed: function(e) {
        var listener = undefined,
            key = undefined

        switch (e.keyCode) {
            case 32: key = 'space'; break;
            case 37: key = 'left'; break;
            case 39: key = 'right'; break;
            case 38: key = 'up'; break;
            case 40: key = 'down'; break;
        }
        listener = this.findKeyListener(key)
        if(listener) {
            listener()
        }
    }
}

// 业务代码..........
var onscreenCanvas = document.getElementById('canvas'),
    onscreenContext = onscreenCanvas.getContext('2d'),
    offscreenCanvasPanda = document.createElement('canvas'),
    offscreenCanvasBamboo = document.createElement('canvas'),
    offscreenContextPanda = offscreenCanvasPanda.getContext('2d'),
    offscreenContextBamboo = offscreenCanvasBamboo.getContext('2d'),
    imageBamboo = new Image(),
    imagePanda = new Image();

var isCollisions = false

offscreenCanvasPanda.id = `panda`
offscreenCanvasBamboo.id = `bamboo`

offscreenCanvasPanda.width = offscreenCanvasBamboo.width = 200
offscreenCanvasPanda.height = offscreenCanvasBamboo.height = 100

var offscreenCanvasWrap = document.getElementById('offscreenCanvasWrap')
offscreenCanvasWrap.querySelector('.panda').appendChild(offscreenCanvasPanda)
offscreenCanvasWrap.querySelector('.bamboo').appendChild(offscreenCanvasBamboo)

function Sprite(arg) {
    this.left = arg.left || 0
    this.top = arg.top || 0
    this.width = arg.width || 10
    this.height = arg.height || 10
    this.visible = true
    this.image = arg.image
}

Sprite.prototype = {
    paint: function(context) {
        if(this.visible) {
            context.save()
            context.drawImage(this.image, 0, 0, this.image.width, this.image.height,
                this.left, this.top, this.width, this.height)
            context.restore()
        }
    }
}

function detectIntersection(rect1, rect2) {
    var rect2CenterX = rect2.left + rect2.width/2,
        rect2CenterY = rect2.top + rect2.height/2,
        rect1CenterX = rect1.left + rect1.width/2,
        rect1CenterY = rect1.top + rect1.height/2;

    // 加上 = 就是相切
    if((Math.abs(rect2CenterX - rect1CenterX) < rect1.width / 2 + rect2.width / 2) &&
        Math.abs(rect2CenterY - rect1CenterY) < rect1.height / 2 + rect2.height / 2) {
        return true
    } else {
        return false
    }
}

function getIntersectionRect(rect1, rect2) {
    var rect1Right = rect1.left + rect1.width,
        rect1Bottom = rect1.top + rect1.height,
        rect2Right = rect2.left + rect2.width,
        rect2Bottom = rect2.top + rect2.height;

    var rect3Left = Math.max(rect1.left, rect2.left),
        rect3Top = Math.max(rect1.top, rect2.top),
        rect3Right = Math.min(rect1Right, rect2Right),
        rect3Bottom = Math.min(rect1Bottom, rect2Bottom);

    return {
        left: rect3Left,
        top: rect3Top,
        width: rect3Right - rect3Left,
        height: rect3Bottom - rect3Top
    }
}

// rect 是交集矩形
function handleEgdeCollisions(rect) {
    // console.log(rect)
    var imgData1 = offscreenContextPanda.getImageData(rect.left, rect.top, rect.width, rect.height),
        imgData2 = offscreenContextBamboo.getImageData(rect.left, rect.top, rect.width, rect.height);
    var imgData1Data = imgData1.data
    var imgData2Data = imgData2.data

    for(var i = 3, len = imgData1Data.length; i < len; i += 4) {
        if(imgData1Data[i] > 0 && imgData2Data[i] > 0) {
            console.log('撞了')
            return true
        }
    }
    return false
}

var bamboo = new Sprite({
    width: 30,
    height: 30,
    left: 60,
    top: 10,
    image: imageBamboo
})

var panda = new Sprite({
    width: 30,
    height: 30,
    top: 10,
    left: 10,
    image: imagePanda
})


var keyPress = new KeyPress()
keyPress.addKeyListener({
    key: 'right',
    listener: function() {
        panda.left += 1
    }
})

keyPress.addKeyListener({
    key: 'left',
    listener: function() {
        panda.left -= 1
    }
})

keyPress.addKeyListener({
    key: 'up',
    listener: function() {
        panda.top -= 1
    }
})

keyPress.addKeyListener({
    key: 'down',
    listener: function() {
        panda.top += 1
    }
})

window.addEventListener('keypress', function(e) {
    e.preventDefault()
    keypressHandle(e)
}, false)
window.addEventListener('keydown', function(e) {
    e.preventDefault()
    keypressHandle(e)
}, false)

function draw() {
    onscreenContext.clearRect(0, 0, onscreenCanvas.width, onscreenCanvas.height)
    offscreenContextPanda.clearRect(0, 0, offscreenCanvasPanda.width, offscreenCanvasPanda.height)
    offscreenContextBamboo.clearRect(0, 0, offscreenContextBamboo.width, offscreenContextBamboo.height)

    bamboo.paint(offscreenContextBamboo)
    panda.paint(offscreenContextPanda)
    bamboo.paint(onscreenContext)
    panda.paint(onscreenContext)

    onscreenContext.save()
    onscreenContext.font = '16px Arial';

    if(isCollisions) {
        onscreenContext.fillText('collision', 15, canvas.height - 10);
    } else {
        onscreenContext.fillText('通过↑↓←→键移动元素', 15, canvas.height - 10);
    }
    onscreenContext.restore()
}

imagePanda.onload = function() {
    draw()
}

function keypressHandle(e) {
    keyPress.keyPressed(e)
    if(detectIntersection(panda, bamboo)) {
        var intersectionRect = getIntersectionRect(panda, bamboo)
        isCollisions = handleEgdeCollisions(intersectionRect)
    }
    draw()
}


imageBamboo.src = ''
imagePanda.src = ''
